package likou.jindian;

import java.util.Arrays;

/**
 * @author: Tangxz
 * @email: 1171702529@qq.com
 * @cate: 2020/12/24 08:25
 */
public class _05_04 {
    public static void main(String[] args) {
//        System.out.println(Integer.toBinaryString(1156403390));
//        System.out.println(Integer.toBinaryString(1156403422));
//        System.out.println(Integer.toBinaryString(1156403407));
        System.out.println(Arrays.toString(findClosedNumbers1(1156403390)));
    }
    public static int[] findClosedNumbers1(int num) {
        int n = Integer.bitCount(num);
        int x = num;
        int min = -1, max = -1;
        while(x<Integer.MAX_VALUE){
            ++x;
            int now = Integer.bitCount(x);
            if(now==n){
                max = x;
                break;
            }
        }
        x = num;
        while(x>1){
            --x;
            if(Integer.bitCount(x)==n){
                min = x;
                break;
            }
        }
        return new int[]{max, min};
    }
    public static int[] findClosedNumbers(int num) {
        int next=-1,front=-1;
        int deep = 0;
        int numdeep = num;
        //目的：1001000100 -> 1001000010，右边最后一个1向右一位。
        //找到右边第一个1右边是0的位置，
        //左边第二个0的左边是1，此时记录目的：1001000100，^11<<1，异或
        boolean seF = true;
        boolean seN = true;
        int sfLO = 0;
        while(numdeep!=1){
            //找到Front
            //后面的1全都要移到最前面
            if(numdeep%2==1){
                sfLO++;
            }
            if(seF&&numdeep%2==0&&(numdeep/2)%2==1){
                int nowSfLO = sfLO+1;
                front = num|((1<<(deep+1))-1);
                front^=((1<<(deep+2))-1);
                int now = 0;
                for(int i=0;i<nowSfLO;i++){
                    now+=(1<<i);
                }
                front|=(now<<(deep-nowSfLO+1));
                seF = false;
            }
            //找到next
            //1001000100，1001001000=原^11<<2
            //全部1都要移到最后面
            if(seN&&numdeep%2==1&&(numdeep/2)%2==0){
                int nowSfLO = sfLO-1;//需要移动的1的个数
                next = num^(3<<deep);
                next |= ((1<<deep)-1);
                next ^= ((1<<deep)-1);
                int now = 0;
                for(int i=0;i<nowSfLO;i++){
                    now+=(1<<i);
                }
                next |= now;
                seN = false;
            }
            deep++;
            numdeep/=2;
        }
        if(seN&&deep<30){
            next = num^(3<<deep);
        }
        //右边第一个1向左和0换，其它1放在最右
        //大于的如果是第32位，则直接返回-1；

        return new int[]{next,front};
    }
}
